﻿using System;
using System.Collections.Generic;
using System.Xml.Linq;
using MediaPortal.GUI.Library;
using System.Threading;
using System.Text.RegularExpressions;
using System.Windows.Forms;

namespace MyNetflix2
{
    public class oDataCalls : Queue
    {
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="user"></param>
        public oDataCalls(User user)
            : base(user)
        { }

        /// <summary>
        /// Refresh the oDataItem Queue
        /// </summary>
        /// <param name="titleId"></param>
        public new List<ODataItem> Refresh(string titleId, Formats.DiscFormat discFormat)
        {
            //--------------------------------------------------------------------------------
            // Create a ODataItem object to dump the information
            //--------------------------------------------------------------------------------
            ODataItem dataItem = null;

            //--------------------------------------------------------------------------------
            // Define the namspaces for the XML
            //--------------------------------------------------------------------------------
            XNamespace atom = "http://www.w3.org/2005/Atom";
            XNamespace msft = "http://schemas.microsoft.com/ado/2007/08/dataservices/metadata";
            XNamespace msft2 = "http://schemas.microsoft.com/ado/2007/08/dataservices";

            try
            {
                //--------------------------------------------------------------------------------
                // Load the xml into an XDocument
                //--------------------------------------------------------------------------------
                XDocument odataCall = XDocument.Load(titleId);

                //--------------------------------------------------------------------------------
                // Now lets parse the information
                //--------------------------------------------------------------------------------
                foreach (XElement xe in odataCall.Descendants(atom + "entry"))
                {
                    dataItem = new ODataItem();

                    //--------------------------------------------------------------------------------
                    // We're only looking for 'entry' elements
                    //--------------------------------------------------------------------------------
                    foreach (XElement entry in xe.Elements())
                    {
                        //--------------------------------------------------------------------------------
                        // Parse the basic information first, Id, Title, Summary, Updated and Links
                        //--------------------------------------------------------------------------------
                        switch (entry.Name.LocalName)
                        {
                            case "id":
                                dataItem.ID = entry.Value;
                                break;
                            case "title":
                                dataItem.Title = entry.Value;
                                break;
                            case "summary":
                                dataItem.Synopsis = Regex.Replace(entry.Value, "<[^>]*>", string.Empty);
                                break;
                            case "updated":
                                dataItem.Updated = DateTime.Parse(entry.Value);
                                break;
                            case "link":
                                if (entry.Attribute("rel").Value.Contains("http://"))
                                {
                                    switch (entry.Attribute("rel").Value.Remove(0, entry.Attribute("rel").Value.ToString().LastIndexOf('/') + 1))
                                    {
                                        case "AudioFormats":
                                            break;
                                        case "Awards":
                                            break;
                                        case "Disc":
                                            dataItem.DiscLink = entry.Attribute("rel").Value;
                                            break;
                                        case "Movie":
                                            break;
                                        case "Season":
                                            dataItem.SeasonsLink = entry.Attribute("rel").Value;
                                            break;
                                        case "Series":
                                            break;
                                        case "ScreenFormats":
                                            break;
                                        case "Cast":
                                            dataItem.CastLink = entry.Attribute("rel").Value;
                                            break;
                                        case "Languages":
                                            break;
                                        case "Directors":
                                            break;
                                        case "Genres":
                                            dataItem.GenresLink = entry.Attribute("rel").Value;
                                            break;
                                    }
                                }
                                break;
                        }
                    }

                    //--------------------------------------------------------------------------------
                    // Now lets parse all the properties
                    //--------------------------------------------------------------------------------
                    foreach (XElement property in xe.Descendants(msft + "properties"))
                    {
                        //--------------------------------------------------------------------------------
                        // Lets get the boxart
                        //--------------------------------------------------------------------------------
                        List<string> boxArtList = new List<string>();

                        foreach (XElement boxArt in property.Descendants(msft2 + "BoxArt"))
                        {
                            boxArtList.Add(boxArt.Element(msft2 + "SmallUrl").Value);
                            boxArtList.Add(boxArt.Element(msft2 + "MediumUrl").Value);
                            boxArtList.Add(boxArt.Element(msft2 + "LargeUrl").Value);
                            dataItem.BoxArt = boxArtList;

                            dataItem.CoverId = boxArt.Element(msft2 + "LargeUrl").Value.Substring(boxArt.Element(msft2 + "LargeUrl").Value.LastIndexOf("/") + 1, boxArt.Element(msft2 + "LargeUrl").Value.LastIndexOf(".") - boxArt.Element(msft2 + "LargeUrl").Value.LastIndexOf("/") - 1);
                        }

                        //--------------------------------------------------------------------------------
                        // Lets get the Ratins, release year, runtime, and the very important NetflixApiID
                        // The NetflixApiId is used to add, remove movies via the API
                        //--------------------------------------------------------------------------------                    
                        dataItem.AverageRating = property.Element(msft2 + "AverageRating") != null ? property.Element(msft2 + "AverageRating").Value : "";
                        dataItem.ReleaseYear = property.Element(msft2 + "ReleaseYear") != null ? int.Parse(property.Element(msft2 + "ReleaseYear").Value) : 0;
                        dataItem.RunTime = (property.Element(msft2 + "Runtime") != null && property.Element(msft2 + "Runtime").Value != "") ? int.Parse(property.Element(msft2 + "Runtime").Value) : 0;
                        dataItem.TitleRef = property.Element(msft2 + "NetflixApiId") != null ? property.Element(msft2 + "NetflixApiId").Value : "";
                        dataItem.Ratings.Add(property.Element(msft2 + "Rating") != null ? property.Element(msft2 + "Rating").Value : "");

                        //--------------------------------------------------------------------------------
                        // Now lets check to see if it is a series or season
                        //--------------------------------------------------------------------------------
                        if (property.Element(msft2 + "Type").Value == "Series" || property.Element(msft2 + "Type").Value == "Season")
                            dataItem.IsSeries = true;
                        else
                            dataItem.IsSeries = false;

                        //--------------------------------------------------------------------------------
                        // Now lets get the Instant Availability Information
                        //--------------------------------------------------------------------------------

                        Formats formats = null;
                        foreach (XElement instant in property.Descendants(msft2 + "Instant"))
                        {
                            formats = new Formats();
                            formats.Format = Formats.DiscFormat.Instant;
                            if (instant.Element(msft2 + "Available").Value != "") dataItem.IsInstant = bool.Parse(instant.Element(msft2 + "Available").Value);
                            if (instant.Element(msft2 + "AvailableFrom").Value != "")
                            {
                                formats.AvailableFrom = DateTime.Parse(instant.Element(msft2 + "AvailableFrom").Value);
                                if (discFormat.ToString().ToLower() == "instant")
                                    dataItem.Availability = DateTime.Parse(instant.Element(msft2 + "AvailableFrom").Value).ToShortDateString();
                            }
                            if (instant.Element(msft2 + "AvailableTo").Value != "") formats.AvailableUntil = DateTime.Parse(instant.Element(msft2 + "AvailableTo").Value);
                            dataItem.TitleFormats.Add(formats);
                        }

                        //--------------------------------------------------------------------------------
                        // Now lets get the Dvd Availability Information
                        //--------------------------------------------------------------------------------
                        foreach (XElement dvd in property.Descendants(msft2 + "Dvd"))
                        {
                            formats = new Formats();
                            formats.Format = Formats.DiscFormat.DVD;
                            if (dvd.Element(msft2 + "AvailableFrom") != null && dvd.Element(msft2 + "AvailableFrom").Value != "")
                            {
                                formats.AvailableFrom = DateTime.Parse(dvd.Element(msft2 + "AvailableFrom").Value);
                                dataItem.IsDvd = true;

                                if (discFormat.ToString().ToLower() == "dvd")
                                    dataItem.Availability = DateTime.Parse(dvd.Element(msft2 + "AvailableFrom").Value).ToShortDateString();
                            }
                            if (dvd.Element(msft2 + "AvailableTo") != null && dvd.Element(msft2 + "AvailableTo").Value != "") formats.AvailableUntil = DateTime.Parse(dvd.Element(msft2 + "AvailableTo").Value);
                            dataItem.TitleFormats.Add(formats);
                        }


                        //--------------------------------------------------------------------------------
                        // Now lets get the BluRay Availability Information
                        //--------------------------------------------------------------------------------
                        foreach (XElement bluray in property.Descendants(msft2 + "BluRay"))
                        {
                            formats = new Formats();
                            formats.Format = Formats.DiscFormat.BluRay;
                            if (bluray.Element(msft2 + "AvailableFrom") != null && bluray.Element(msft2 + "AvailableFrom").Value != "")
                            {
                                dataItem.IsBluRay = true;
                                formats.AvailableFrom = DateTime.Parse(bluray.Element(msft2 + "AvailableFrom").Value);

                                if (discFormat.ToString().ToLower() == "bluray")
                                    dataItem.Availability = DateTime.Parse(bluray.Element(msft2 + "AvailableFrom").Value).ToShortDateString();
                            }
                            if (bluray.Element(msft2 + "AvailableTo") != null && bluray.Element(msft2 + "AvailableTo").Value != "") formats.AvailableUntil = DateTime.Parse(bluray.Element(msft2 + "AvailableTo").Value);
                            dataItem.TitleFormats.Add(formats);


                        }
                    }

                    Thread background = new Thread(dataItem.GetBackgroundImage);
                    background.Start();
                    dataItem.GetCoverImage(dataItem.BoxArt[2].ToString());

                    ODataItems.Add(dataItem);

                    Log.Debug("My NetFlix - oDataCalls:Refresh(): Movie " + dataItem.Title + " added to ODataItems");
                }

                return ODataItems;
            }
            catch (Exception ex)
            {
                Log.Error("My NetFlix - oDataCalls:Refresh(): Error - " + ex.Message);
                return null;
            }
        }
    }
}
